package org.mybatis.generator.codegen.mybatis3.javaservice;

import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.Plugin;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.codegen.AbstractJavaGenerator;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import static org.mybatis.generator.internal.util.JavaBeansUtil.getGetterMethodName;
import static org.mybatis.generator.internal.util.JavaBeansUtil.getSetterMethodName;

public class ApiVoGenerator extends AbstractJavaGenerator {
	Properties properties;

	public ApiVoGenerator(Properties properties) {
		this.properties = properties;
	}

	@Override
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List<CompilationUnit> getCompilationUnits() {
		String vo = properties.getProperty("targetVoPackage");
		
		Plugin plugins = context.getPlugins();
		CommentGenerator commentGenerator = context.getCommentGenerator();

		FullyQualifiedJavaType type = new FullyQualifiedJavaType(  
	            new StringBuffer(vo).append(".").
	          append(introspectedTable.getFullyQualifiedTable().getDomainObjectName()).  
	          append("Vo").toString());
		
		TopLevelClass topLevelClass = new TopLevelClass(type);
		topLevelClass.setVisibility(JavaVisibility.PUBLIC);
		commentGenerator.addJavaFileComment(topLevelClass);
		
		topLevelClass.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModel"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType("io.swagger.annotations.ApiModelProperty"));
		topLevelClass.addImportedType(new FullyQualifiedJavaType("lombok.Data"));
		topLevelClass.addAnnotation("@ApiModel");
		topLevelClass.addAnnotation("@Data");

		
		 List<IntrospectedColumn> introspectedColumns = introspectedTable.getAllColumns();

	        for (IntrospectedColumn introspectedColumn : introspectedColumns) {

	            Field field = getJavaBeansField(introspectedColumn);
	            if (plugins.modelFieldGenerated(field, topLevelClass,
	                    introspectedColumn, introspectedTable,
	                    Plugin.ModelClassType.BASE_RECORD)) {
	                topLevelClass.addField(field);
	                topLevelClass.addImportedType(field.getType());
	            }

//	            Method method = getJavaBeansGetter(introspectedColumn);
//	            if (plugins.modelGetterMethodGenerated(method, topLevelClass,
//	                    introspectedColumn, introspectedTable,
//	                    Plugin.ModelClassType.BASE_RECORD)) {
//	                topLevelClass.addMethod(method);
//	            }
//
//	            if (!introspectedTable.isImmutable()) {
//	                method = getJavaBeansSetter(introspectedColumn);
//	                if (plugins.modelSetterMethodGenerated(method, topLevelClass,
//	                        introspectedColumn, introspectedTable,
//	                        Plugin.ModelClassType.BASE_RECORD)) {
//	                    topLevelClass.addMethod(method);
//	                }
//	            }
	        }

	        List<CompilationUnit> answer = new ArrayList<CompilationUnit>();
	            answer.add(topLevelClass);

		return answer;
	}
	
	public Field getJavaBeansField(IntrospectedColumn introspectedColumn) {
        FullyQualifiedJavaType fqjt = introspectedColumn
                .getFullyQualifiedJavaType();
        String property = introspectedColumn.getJavaProperty();

        Field field = new Field();
        field.setVisibility(JavaVisibility.PRIVATE);
        field.setType(fqjt);
        field.setName(property);
       String remark=introspectedColumn.getRemarks();
        if (StringUtility.stringHasValue(remark)) {
            field.addJavaDocLine("/**");
            StringBuilder sb = new StringBuilder();
            sb.append(" * ");
            sb.append(introspectedColumn.getRemarks());
            field.addJavaDocLine(sb.toString());
            field.addJavaDocLine(" */");
        }
        
        field.addAnnotation("@ApiModelProperty(value = \"" + remark + "\",required = true)");
        return field;
    }
	
	
	public Method getJavaBeansGetter(IntrospectedColumn introspectedColumn) {
        FullyQualifiedJavaType fqjt = introspectedColumn
                .getFullyQualifiedJavaType();
        String property = introspectedColumn.getJavaProperty();

        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setReturnType(fqjt);
        method.setName(getGetterMethodName(property, fqjt));
        context.getCommentGenerator().addGetterComment(method,
                introspectedTable, introspectedColumn);

        StringBuilder sb = new StringBuilder();
        sb.append("return "); //$NON-NLS-1$
        sb.append(property);
        sb.append(';');
        method.addBodyLine(sb.toString());

        return method;
    }
	
	public Method getJavaBeansSetter(IntrospectedColumn introspectedColumn) {
        FullyQualifiedJavaType fqjt = introspectedColumn
                .getFullyQualifiedJavaType();
        String property = introspectedColumn.getJavaProperty();

        Method method = new Method();
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setName(getSetterMethodName(property));
        method.addParameter(new Parameter(fqjt, property));
//        context.getCommentGenerator().addSetterComment(method,
//                introspectedTable, introspectedColumn);

        StringBuilder sb = new StringBuilder();
        if (isTrimStringsEnabled() && introspectedColumn.isStringColumn()) {
            sb.append("this."); //$NON-NLS-1$
            sb.append(property);
            sb.append(" = "); //$NON-NLS-1$
            sb.append(property);
            sb.append(" == null ? null : "); //$NON-NLS-1$
            sb.append(property);
            sb.append(".trim();"); //$NON-NLS-1$
            method.addBodyLine(sb.toString());
        } else {
            sb.append("this."); //$NON-NLS-1$
            sb.append(property);
            sb.append(" = "); //$NON-NLS-1$
            sb.append(property);
            sb.append(';');
            method.addBodyLine(sb.toString());
        }

        return method;
    }
	
}
